const TradingStrategy = require('./TradingStrategy');
const Order = require('../core/Order');

/**
 * 羊群效应策略
 * 投资者倾向于跟随大多数人的行为
 */
class HerdBehaviorStrategy extends TradingStrategy {
  /**
   * 决策方法
   * @param {MarketEnvironment} market - 市场环境
   * @param {Investor} investor - 投资者
   * @returns {Order|null} 订单或null
   */
  decide(market, investor) {
    // 随机决定是否交易
    if (Math.random() > 0.3) {
      return null;
    }

    // 随机选择一个资产
    const assets = Array.from(market.assets.values());
    if (assets.length === 0) {
      return null;
    }
    
    const asset = assets[Math.floor(Math.random() * assets.length)];
    const orderBook = market.orderBooks.get(asset.id);
    
    if (!orderBook) {
      return null;
    }
    
    // 分析订单簿中的买卖压力
    const buyPressure = this.calculatePressure(orderBook.buyOrders);
    const sellPressure = this.calculatePressure(orderBook.sellOrders);
    
    // 根据压力对比决定交易方向
    let isBuy = false;
    if (buyPressure > sellPressure) {
      // 买压大于卖压，跟随买入
      isBuy = true;
    } else if (sellPressure > buyPressure) {
      // 卖压大于买压，跟随卖出
      isBuy = false;
    } else {
      // 压力相等，随机决定
      isBuy = Math.random() > 0.5;
    }
    
    // 确定交易价格和数量
    const currentPrice = asset.getPrice();
    const priceVariation = (Math.random() - 0.5) * 0.02; // ±1%的价格波动
    const price = currentPrice * (1 + priceVariation);
    
    // 根据投资者资本确定交易数量
    const maxAffordable = isBuy ? 
      Math.floor(investor.capital / price) : 
      investor.getPosition(asset.id).quantity;
      
    if (maxAffordable <= 0) {
      return null;
    }
    
    // 根据压力差确定交易数量
    const pressureRatio = Math.max(buyPressure, sellPressure) / (buyPressure + sellPressure + 1);
    const quantity = Math.min(
      Math.ceil(maxAffordable * pressureRatio * 0.5),
      maxAffordable
    );
    
    if (quantity <= 0) {
      return null;
    }
    
    return new Order(
      investor.id,
      asset.id,
      isBuy ? 'buy' : 'sell',
      price,
      quantity
    );
  }
  
  /**
   * 计算订单压力
   * @param {Array} orders - 订单数组
   * @returns {number} 压力值
   */
  calculatePressure(orders) {
    // 简单计算订单总价值作为压力指标
    return orders.reduce((pressure, order) => {
      return pressure + (order.price * order.quantity);
    }, 0);
  }
}

module.exports = HerdBehaviorStrategy;